package com.lxw.oa.util;

import com.lxw.oa.entity.SystemLog;
import com.lxw.oa.entity.User;
import com.lxw.oa.service.BaseService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

@Aspect
@Component
public class LogAop {
    //private Logger logger = LogManager.getLogger(getClass());

    @Autowired
    private BaseService baseService;

    @Pointcut("execution(public * com.lxw.oa.controller.common..*.Log_*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String[] moduleMessage = getMthodRemark(joinPoint);
        Date occurrTime=new Date();
        DateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //HH表示24小时制；
        String formatDate = dFormat.format(occurrTime);
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String name="未登录用户";
        if(user!=null){
            name=user.getName();
        }
        //方法全名
        //String Allmothod=joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        String[] controllerStr=joinPoint.getSignature().getDeclaringTypeName().split("\\.");
        //System.out.println("==================="+joinPoint.getSignature().getDeclaringTypeName());
        //System.out.println("==================="+controllerStr.length);
        String url=request.getRequestURL().toString().split(":")[2];
        String ip=request.getRemoteAddr();
        if("0:0:0:0:0:0:0:1".equals(ip)||"127.0.0.1".equals(ip)){
            ip="本机登陆";
        }
        String method=controllerStr[controllerStr.length-1]+"."+joinPoint.getSignature().getName();
        //参数明细数组
        //String args=Arrays.toString(joinPoint.getArgs());
        String argsLength=joinPoint.getArgs().length+"";
        SystemLog systemLog=new SystemLog(url,name,ip,method,argsLength,moduleMessage[0],moduleMessage[1],formatDate);
        baseService.systemLogAdd(systemLog);

        // 记录下请求内容
/*        logger.info("请求地址 : " + request.getRequestURL().toString());
        logger.info("请求方法 : " + request.getMethod());
        logger.info("请求IP : " + request.getRemoteAddr());
        logger.info("请求方法具体名称 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("请求参数 : " + Arrays.toString(joinPoint.getArgs()));
        logger.info("方法标识 : " + methodRemark);*/

    }

/*    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求，返回内容
        logger.info("返回信息 : " + ret);
    }*/


    // 获取方法的中文备注____用于记录用户的操作日志描述  
    public static String[] getMthodRemark(JoinPoint joinPoint)
            throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Class targetClass = Class.forName(targetName);
        Method[] method = targetClass.getMethods();
        String[] methode = new String[2];
        for (Method m : method) {
            if (m.getName().equals(methodName)) {
                    LogAopIn methodCache = m.getAnnotation(LogAopIn.class);
                    if(methodCache==null){
                        break;
                    }
                    methode[0] = methodCache.moduleName();
                    methode[1] = methodCache.option();
                break;
            }
        }
        return methode;
    }












}
